/* Copyright (c) 2008, 2009, 2010, 2011 Damian Kmiecik
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:

   * Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
   * Neither the name of the copyright holders nor the names of
     contributors may be used to endorse or promote products derived
     from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE. */

#ifndef _1WIRE_H_
#define _1WIRE_H_

#include "hardware.h"
#include "main.h"

/** @defgroup ONEWIRE 1-wire search algorithms implementation
	@author Damian Kmiecik
	@bug any knowns

	1-wire implementation contains standard algorithms for searching
	devices on the bus and saving their unique ID. Code based on
	examples sharing by Dallas company.

	@par Notes

	- Bus have to be pull-upped with 4.7k resistor.

	- Temperature reads function, based on simple delays. This wasting
	CPU time, and breaks the program executing for at least 300ms. If
	you do not wants delays, you must use software timers or
	interrupt-based temperature update.
*/

#ifdef __cplusplus
extern "C" {
#endif

/** @def OW_DEBUG
	@ingroup debug
	Defines the standard method of debugging system.
	If you comment this, there are no debugging messages will be presented.
 */
//#define OW_DEBUG	DEBUG

#ifdef USE_1WIRE

/** Change this consistent with your hardware connections. */
#define OW_PIN		ONEWIRE_PIN
#define OW_PORT		ONEWIRE_PORT
#define OW_DDR		ONEWIRE_DDR
#define OW_PINP		ONEWIRE_PINx

/** @def OW_TABLE_SIZE
	@ingroup ONEWIRE
	Defines the size of OW_TABLE. Also describes the maximum amount
	of 1wire devices connected to.
*/
#define OW_TABLE_SIZE	8

/** @var OW_TABLE
	@ingroup ONEWIRE
	Preserve the unique ID's of 1-wire devices.
*/
extern uint8_t OW_TABLE[OW_TABLE_SIZE][8];

/** @var OW_cnt
	@ingroup ONEWIRE
	Contains the amount of devices has been found on the bus.
*/
extern uint8_t OW_cnt;

/** @var ROM_NO
	@ingroup ONEWIRE
	Temporary device ID. It is used for some functions
	for returns or taking parameters.
*/
extern unsigned char ROM_NO[8];

/** @ingroup ONEWIRE
	Initialize the bus.
	@note Must be call before any using of OW functions.
*/
extern void OWInit(void);

/** @ingroup ONEWIRE
	Find the first device on the 1-wire bus.
	In association with function \a OWNext it is possibly
	to find all devices connected to the 1-wire bus.
	Function stores ID in \a OW_ROM array.
	@returns if device found: 1, if no devices: 0
*/
extern uint8_t OWFirst(void);

/** @ingroup ONEWIRE
	Find the next devices on the 1-wire bus.
	@note Function \a OWFirst launch the searching procedure,
	so there must be exactly one call to this function before
	any calling to \a OWNext
	@returns if device found: 1, if no devices: 0
*/
extern uint8_t OWNext(void);

/** @ingroup ONEWIRE
	Functions check that specified devices exists on the bus.
	@param OW_ROM variable preserve device ID
	@returns 1 if device presents, else 0
*/
extern uint8_t OWVerify(void);

/** @ingroup ONEWIRE
	Setup the search to find the device type 'family_code' on the next
	call to OWNext() if it is present.
	@param family_code Code of family-tree of 1-wire devices.
*/
extern void OWTargetSetup(uint8_t family_code);

/** @ingroup ONEWIRE
	Setup the search to skip the current device type on the next call to \a OWNext().
*/
extern void OWFamilySkipSetup(void);

/** @ingroup ONEWIRE
	Reset 1-wire bus pulse.
	@returns 1 if there is some devices on the bus, else 0
*/
extern uint8_t OWReset(void);

/** @ingroup ONEWIRE
	Write byte to the bus.
	@param byte_value Value to write.
*/
extern void OWWriteByte(uint8_t byte_value);

/** @ingroup ONEWIRE
	Read byte from the bus.
	@returns Read value
*/
extern uint8_t OWReadByte(void);

/** @ingroup ONEWIRE
	Function find all devices on the bus.
	@returns ID stored at \a OW_TABLE
*/
extern void OWFindAll(void);

/** @ingroup ONEWIRE
	Read temperature from desired devices
	@param addr Address number in OW_TABLE that stores device ID.
	@returns Signed temperature value.
*/
extern int8_t OWReadTemperature(const uint8_t addr);

/** @ingroup ONEWIRE
	Compute crc8 checksum.
	@param value data
	@returns CRC8
*/
extern uint8_t docrc8(uint8_t value);

#endif

#endif
